package gui.customizer.panes.netfilter;

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.IOException;

import javax.swing.BorderFactory;
import javax.swing.JList;
import javax.swing.JPanel;
import javax.swing.ListSelectionModel;

import net.SSHConnectionProxy;
import net.miginfocom.swing.MigLayout;
import javax.swing.JScrollPane;
import javax.swing.JButton;
import javax.swing.JTabbedPane;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;

import core.models.FlushRule;
import core.models.NatRule;
import core.models.RuleSet;

public class NAT extends JPanel {
	/**
	 * 
	 */
	private static final long serialVersionUID = 6062325778644899848L;
	private SaveAndSend saveAndSend;
	private JList listRules;
	private JButton btnDelete;
	private JTabbedPane tabbedPane;
	private NatConfigurable connectionSharing;
	private NatConfigurable portForwarding;
	private NatConfigurable redirection;
	private JScrollPane connectionSharingScroller;
	private JScrollPane portForwardingScroller;
	private JScrollPane redirectionScroller;

	public NAT() {
		setLayout(new MigLayout("", "[grow][]", "[][][100px]15[grow]"));

		// Save and send Panel
		saveAndSend = new SaveAndSend();
		add(saveAndSend, "cell 0 0 2 1,grow");

		listRules = new JList();
		listRules.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
		listRules.setLayoutOrientation(JList.VERTICAL);

		JScrollPane listScroller = new JScrollPane(listRules);
		listScroller.setBorder(BorderFactory.createTitledBorder("NAT Rules"));
		add(listScroller, "cell 0 1 1 2,grow");

		btnDelete = new JButton("Delete");
		add(btnDelete, "cell 1 1");

		connectionSharing = new ConnectionSharing();
		portForwarding = new PortForwarding();
		redirection = new Redirection();

		connectionSharingScroller = new JScrollPane(connectionSharing);
		portForwardingScroller = new JScrollPane(portForwarding);
		redirectionScroller = new JScrollPane(redirection);

		tabbedPane = new JTabbedPane(JTabbedPane.TOP);
		tabbedPane.add(connectionSharingScroller, "Connection Sharing");
		tabbedPane.add(portForwardingScroller, "Port Forwarding");
		tabbedPane.add(redirectionScroller, "Redirection");
		add(tabbedPane, "cell 0 3,grow");

		// Initialize
		try {
			initialize();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

	private void initialize() throws IOException {
		final RuleSet rs = new RuleSet();
		rs.loadRemoteRules("nat");

		listRules.setModel(rs);
		listRules.addListSelectionListener(new ListSelectionListener() {
			@Override
			public void valueChanged(ListSelectionEvent e) {
				if (e.getValueIsAdjusting())
					return;
				NatRule rule = (NatRule) listRules.getSelectedValue();
				if (rule != null)
					setProperPanel(rule);
			}
		});

		addButtonAddActionListener(connectionSharing, rs);
		addButtonAddActionListener(portForwarding, rs);
		addButtonAddActionListener(redirection, rs);

		btnDelete.addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent e) {
				if (listRules.getSelectedIndex() != -1) {
					int index = listRules.getSelectedIndex();
					rs.remove(index);
					if (index == rs.getSize())
						index--;
					listRules.setSelectedIndex(index);
				}
			}
		});
		
		saveAndSend.addListenerToSendButton(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent e) {
				if (!SSHConnectionProxy.isConnected())
					return;
				if (saveAndSend.ShouldAddFlushRules()) {
					FlushRule flush = new FlushRule("-F", "nat");
					rs.getFlushRuleSet().add(flush);
				}
				try {
					rs.sendRules("nat");
				} catch (IOException e1) {
					// TODO Auto-generated catch block
					e1.printStackTrace();
				}
			}
		});
	}

	private void setProperPanel(NatRule rule) {
		String[] target = rule.getOptions().get("-j").split(" ");
		if (target[0].equals("SNAT") || target[0].equals("MASQUERADE")) {
			connectionSharing.setRule(rule);
			tabbedPane.setSelectedComponent(connectionSharingScroller);
			portForwarding.resetFields();
			redirection.resetFields();
		} else if (target[0].equals("DNAT")) {
			portForwarding.setRule(rule);
			tabbedPane.setSelectedComponent(portForwardingScroller);
			connectionSharing.resetFields();
			redirection.resetFields();
		} else if (target[0].equals("REDIRECT")) {
			redirection.setRule(rule);
			tabbedPane.setSelectedComponent(redirectionScroller);
			connectionSharing.resetFields();
			portForwarding.resetFields();
		}
	}

	private void addButtonAddActionListener(final NatConfigurable configurable,
			final RuleSet rs) {
		configurable.addListenerToAddButton(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent e) {
				NatRule rule = configurable.getRule();
				rs.addElement(rule);
				listRules.setSelectedValue(rule, true);
			}
		});
	}

}
